-- if not IsAddOnLoaded("Grid") then return end
	
local addon = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0")

local BS = AceLibrary("Babble-Spell-2.2")

local HOTS = {
	-- Druid
	BS["Regrowth"] = { duration = 21, color = { r = 1, g = 0.2, b = 0.9 } },
	BS["Rejuvenation"] = { duration = 12, color = { r = 0.3, g = 0.9, b = 0 } },
	BS["Lifebloom"] = { duration = 7, stacks = 3, color = {
			[1] = { r = 0.5, g = 0.6, b = 0.5 },
			[2] = { r = 0.5, g = 0.8, b = 0.5 },
			[3] = { r = 0.5, g = 1, b = 0.5 },
		} },
	-- Priest
	BS["Renew"] = { duration = 15, color = { r = 1, g = 1, b = 1 } },
	-- Draeni
	BS["Gift of the Naaru"] = { duration = 15, color = { r = 1, g = 1, b = 0.1 } },
}

function addon:OnInitialize()
	self:RegisterEvent("UNIT_SPELLCAST_SENT")
	-- self:RegisterEvent("UNIT_SPELLCAST_START")
	self:RegisterEvent("UNIT_SPELLCAST_FAILED")
	self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", "UNIT_SPELLCAST_FAILED")
	self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
	self:RegisterEvent("SpecialEvents_UnitBuffLost")
end

function addon:GetGridFrame(unit)
	assert(unit)
	for _, frame in pairs(GridFrame.registeredFrames) do
		if frame.unit == unit then
			return frame
		end
	end
end

function addon:GetAgufFrame(unit)
end

function addon:SpecialEvents_UnitBuffLost(unit, spell)
	local f = self:GetGridFrame(unit)
	if f and f.dstb then
		for _, sb in ipairs(f.dstb) do
			if sb.spell == spell then
				self:OnFrameUpdate(sb, sb:GetValue() + 1)
				break
			end
		end
	end
	f = self:GetAgufFrame(unit)
	if f and f.dstb then
		for _, sb in ipairs(f.dstb) do
			if sb.spell == spell then
				self:OnFrameUpdate(sb, sb:GetValue() + 1)
				break
			end
		end
	end
end

function addon:UNIT_SPELLCAST_SENT(unit, spell, rank, target)
	if unit ~= "player" and not HOTS[spell] then return end
	self.spell = spell
	self.target = target
	-- self.rank = rank
end

function addon:UNIT_SPELLCAST_FAILED(unit)
	if unit ~= "player" then return end
	self.spell = nil
end

function addon:UNIT_SPELLCAST_SUCCEEDED(unit)
	if unit ~= "player" then return end
	if not self.spell then return end
	
	self:OnCast(self.spell, self.target)
	
	self.spell = nil
end

function addon:OnCast(spell, unit)
	local f = self:GetGridFrame(unit)
	if f then
		self:HandleFrame(spell, f)
	end
	f = self:GetAgufFrame(unit)
	if f then
		self:HandleFrame(spell, f)
	end
end

function addon:HandleFrame(spell, frame)
	local dstb = frame.dstb
	if not dstb then
		dstb = {}
		frame.dstb = dstb
	end
	for _, sb in ipairs(dstb) do
		if sb.spell == nil or sb.spell == spell then
			self:HandleBar(spell, sb)
			return
		end
	end
	if IsInCombatLockdown() then
		self.framesToAdd[frame] = true
	else
		self:HandleBar(spell, self:AddFrame(frame, dstb))
	end
end

function addon:HandleBar(spell, sb, value)
	local info, color = HOTS[spell]
	sb.spell = spell
	if info.stacks then
		local s = (sb.stacks or 0) + 1
		if s > info.stacks then s = info.stacks end
		color = info.color[s]
	else
		color = info.color
	end
	self.bars[sb] = true
	sb:SetStatusBarColor(color.r, color.g, color.b)
	sb:SetMinMaxValues(0, sb.duration)
	sb:SetValue(value or sb.duration)
end

local SB_OnUpdate = function (...)
	addon:OnFrameUpdate(...)
end

function addon:AddFrame(parent, info)
	local frame = CreateFrame("StatusBar", nil, parent)
	frame:SetFrameStrata("TOOLTIP")
	if #info == 0 then
		frame:SetPoint("BOTTOMLEFT")
	else
		frame:SetPoint("BOTTOMLEFT", info[#info], "TOPLEFT")
	end
	frame:SetWidth(parent:GetWidth())
	frame:SetHeight(2)
	info[#info + 1] = frame
	frame:SetScript("OnUpdate", SB_OnUpdate)
	
	return frame
end

function addon:OnFrameUpdate(frame, elapsed)
	if not frame.spell then return end
	local v  = frame:GetValue() - elapsed
	if v > 0 then
		frame:SetValue(v)
		return
	end
	frame:SetValue(0)
	frame.spell = nil
	local info = frame:GetParent().dstb
	local index
	for i, f in ipairs(info) do
		if frame == f then
			index = i + 1
			break
		end
	end
	local curr, prev = info[index], frame
	while curr and curr.spell do
		self:HandleBar(curr.spell, prev, curr:GetValue())
		prev = curr
		index = index + 1
		curr = info[index]
	end
end

